[Chapter 17] 17.2 Rule Set 96
Author: Bryan Costales & Eric Allman
Date: 1999-01-06T18:40:14Z

#

| Chapter 17 The Hub's Complex Rules |

## 17.2 Rule Set 96

After each address has its host part focused by rule set 3, it is passed to rule set 96 (by a subroutine call with the `$>` operator). Rule set 96 verifies that each address is good. It is not used by all configuration files but is used by the configuration files that are distributed with V8 sendmail.

### 17.2.1 Is the Host Local?

First, rule set 96 determines whether the focused host part is really the name of the local machine. This determination is less straightforward than you might think. The special hostname `localhost`, by which all hosts are known, is checked first:

>     R$* < @localhost      >$*       $: $1 <@$j.> $2      Sans domain
>     R$* < @localhost.$m   >$*       $: $1 <@$j.> $2      With domain
>     R$* < @localhost.UUCP >$*       $: $1 <@$j.> $2      With UUCP domain

The name `localhost` is checked in three forms (thus three rules): first as a bare hostname (without a domain part), then with the local domain attached (as stored in `$m`), and finally with the pseudo-name UUCP attached (on the off chance that mail was sent to the local host via UUCP). Later, the class `$=w`, which lists all the names of the local host, will be checked. Here, `localhost` is checked because there is no guarantee that it will be included in `$=w`.

The next three rules handle a host that is in numeric IP form. Such a hostname is formed by surrounding four dot-separated integers with square brackets (like [123.45.67.8]).

>     R$* < @ [$+] > $*            $: $1 <@@ [$2]>$3      is it numeric IP?
>     R$* < @@ $=w > $*            $: $1 <@  $j.> $2      yes. Is it us?
>     R$* < @@ $+  > $*            $@ $1 <@  $2> $3       yes, but not us.

The first of these rules finds anything surrounded by square brackets (it does not care whether that anything is an IP address). If found, it prefixes the host part with an extra `@` so that only the next two rules will see it. The second rule compares the IP address to the list of hostnames in `$=w`. [4] If the IP address is found in `$=w`, the host is changed to the value in `$j` (the local, full canonical hostname). If the IP address is not that of the local host, the third rule causes it to be immediately returned as a valid (but not local) IP address.

> [4] Under V8 sendmail the local host's IP address is automatically added to class `w`. Beginning with V8.7 sendmail, the addresses associated with all network interfaces are also added to the class `w`.

The next two rules in rule set 96 determine whether the hostname is one of those declared as local in class `$=w`:

>     R$* < @ $=w    > $*         $: $1 <@ $j.> $3     us?
>     R$* < @ $=w.$m > $*         $: $1 <@ $j.> $3     us with domain?

The first just examines the list of hosts in the class `$=w` and, if found, converts the workspace to the full canonical name of the local host (`$j.`). The second performs the same search and substitution but appends the local domain (`$m`) to each host in `$=w`. Neither rewrite is returned (no `$@` prefix to the RHS) but is instead carried down to subsequent rules.

At this point, UUCP hosts should be returned as is because the rest of the rules in rule set 96 deal with DNS and canonicalization. The next rule handles this:

>     R$* < @ $+.UUCP > $*        $@ $1 <@$2.UUCP> $3  pass back uucp

This rule looks for any host (`$+`) with a .UUCP suffix and returns (the `$@` prefix to the RHS) that address unchanged. Review Section 17.1.4, "UUCP Addresses" to see how the .UUCP suffix came to be attached in the first place.

Any address that has made it this far is next looked up with DNS:

>     R$* < @ $* $~P > $*         $: $1 <@ $[ $2$3 $]> $4      canonicalize

Here, the notation `$~P` denotes anything that is not in the class `P`. That class was declared elsewhere. It contains a list of pseudo-domains (domains that cannot be looked up with DNS, such as UUCP and BITNET). If the last component of the hostname is other than one of the pseudo-domains, the RHS causes that hostname to be looked up with DNS and replaced with the full canonical name for that host. If the hostname corresponds to a CNAME, it will be replaced with the name of the corresponding A or MX record. If the address is an IP address (such as [123.45.67.80]), a PTR record will be looked up to find the canonical name. If the lookup fails, the name is unchanged. If the lookup succeeds, the canonical name will replace the looked up name and a dot will be appended. [5] On some machines this lookup may use /etc/hosts, nis, nisplus, or some other means defined by your service switch file. In the configuration file that we have been examining, a successful DNS lookup causes a dot to be appended to the resulting hostname. This the same as what has been done all along by adding a dot to `$j`.

> [5] This process is described in more detail in Section 33.4.3, "$[ and $]: A Special Case", which also explains how to change the dot to a different character or characters.

The last few rules merely perform some housekeeping by adding a dot to any valid addresses that lack one:

>     R$* < @ $* $=P > $*         $: $1 <@ $2$3 .> $4        canonicalize pseudos
>     R$* < @ $*..   > $*            $1 <@ $2.> $3           strip extra dots
>     R$* < @ $j     > $*            $1 <@ $2.> $3           canonicalize local

In the first rule, pseudo-domains are considered canonical because there is no way to check their validity. The second rule strips any extra trailing dots in case they may have been added by accident. [6] Finally, a hostname of `$j` is checked, and if it is found, a dot is added, thus finishing rule set 96's job.

> [6] Sometimes `$=P` contains just a dot. In this case, any address that ends with a dot will have that ending dot doubled.

17.1 Rule Set 3 |  | 17.3 Rule Set 0